//== SAGITTARIUS ============================================================================

//== BEGINNING OF CODE ===============================================================

#ifndef __SAGUTTARUIS__REPARSER__H_
#define __SAGUTTARUIS__REPARSER__H_

//== INCLUDES ========================================================================

#include "sagittarius/core/SagittariusCore.h"
#include "sagittarius/re/reAST.h"

//consts are incompatible with switch statements
//have to use #define
/*const UnicodeCChar CONST_RE_AMP    =   0x26;//'&'
const UnicodeCChar CONST_LPAREN =   0x28;//'('
const UnicodeCChar CONST_RPAREN =   0x29;//')'
const UnicodeCChar CONST_VBAR   =   0x7C;//'|'*/

#define CONST_RE_AMP       0x26  /*'&'*/
#define CONST_RE_LPAREN    0x28  /*'('*/
#define CONST_RE_RPAREN    0x29  /*')'*/
#define CONST_RE_STAR      0x2A  /*'*'*/
#define CONST_RE_CARROT    0x5E  /*'^'*/
#define CONST_RE_VBAR      0x7C  /*'|'*/

#ifdef __cplusplus
extern "C" {
#endif

#define REPARSER_COMPUTE_NULLABLE

#define LOOKUP_KEY_TYPE UnicodeCChar
#define LOOKUP_VAL_TYPE lookupVal
#define LOOKUP_N        256

typedef expNode* (parseExpFunc)(const UnicodeCChar x, const UnicodeCChar* w);

typedef struct {
    parseExpFunc* invoke;
} lookupVal;

//Parser state
typedef struct {
    UnicodeCChar x;
    const UnicodeCChar* w;
} parserState;

/**
 * @fn parserState re_createParserState(const UnicodeCChar* w)
 * @brief Create an initial parser state from a unicode buffer */
parserState re_createParserState(const UnicodeCChar* w);

/**
 * @fn UnicodeCChar nextTok(const UnicodeCChar* w)
 * @brief Get the next token */
UnicodeCChar nextTok(const UnicodeCChar* w);
/**
 * @fn UnicodeCChar nextTok(const UnicodeCChar* w)
 * @brief Match the next token */
int match(parserState* state, const UnicodeCChar c);

/**
 * @fn int distributeComplementR(expNode* n)
 * @brief Distributes the complement operator to this node and its children where applicable */
void distributeComplementR(expNode* n);


//Expression parsers
/** @fn expNode* re_parseExpE(parserState* state)
 *  @brief Grammer expansion */
expNode* re_parseExpE(parserState* state);

/** @fn expNode* re_parseExpEp(parserState* state)
 *  @brief Grammer expansion */
expNode* re_parseExpEp(parserState* state);

/** @fn expNode* re_parseExpO(parserState* state)
 *  @brief Grammer expansion */
expNode* re_parseExpO(parserState* state);

/** @fn expNode* re_parseExpOp(parserState* state)
 *  @brief Grammer expansion */
expNode* re_parseExpOp(parserState* state);

/** @fn expNode* re_parseExpT(parserState* state)
 *  @brief Grammer expansion */
expNode* re_parseExpT(parserState* state);

/** @fn expNode* re_parseExpTp(parserState* state)
 *  @brief Grammer expansion */
expNode* re_parseExpTp(parserState* state);

/** @fn expNode* re_parseExpF(parserState* state)
 *  @brief Grammer expansion */
expNode* re_parseExpF(parserState* state);

//Terminal expression(s)
expNode* re_parseExpPrimitive(parserState* state);

#ifdef __cplusplus
}//extern "C"
#endif

#endif
